#include <stdio.h>
#include "aimage.h"
#include "aimage_ppm.h"

class ACCUMCB: public ALINECALLBACK
{
	AVECTOR accum;
	AVECTOR avg;
	int count;
	bool avg_set;
	int m_pixels_above_avg;
	int m_pixels_below_avg;
	float m_avg_mag;

	public:

	ACCUMCB( void ) 
	{ 
		accum.x = 0.0f; 
		accum.y = 0.0f; 
		accum.z = 0.0f; 
		count = 0;
		avg_set = false;
		m_pixels_above_avg = 0;
		m_pixels_below_avg = 0;
	}

	void setpixel( int x, int y, float t, APIXEL &p )
	{
		AVECTOR pa=p;
		AVECTOR pb=pa;

		if ( !avg_set )
		{
			accum=accum + pa;
			count++;
			return;
		}

		pa = pa - avg; 

		if ( pa.mag() > .10f )
		{
			m_pixels_above_avg++;
		}
		if (( pb.mag() / m_avg_mag ) < .6 )
		{
			//printf("%d %d -> %g\n", x, y, pb.mag());
			m_pixels_below_avg++;
		}
	}

	float reset( void )
	{
		m_pixels_above_avg = 0;
		m_pixels_below_avg = 0;
	}

	int pixels_above_avg( void )
	{
		return m_pixels_above_avg;
	}

	int pixels_below_avg( void )
	{
		return m_pixels_below_avg;
	}

	float set_background( void )
	{
		avg_set = true;
		avg = accum * ( 1.0 / ((float) count));
		m_avg_mag = avg.mag();
		printf("Avg is %g %g %g mag %g\n", avg.x, avg.y, avg.z, m_avg_mag );
	}
};

float do_sweep( AIMAGE &image, bool inner,
	float xs, float ys, float sweep_size, float xd, float yd,
	float stopat,  ACCUMCB &cb )
{
	float i;

	for ( i = 0.0f; i < stopat; ++i )
	{
		float xb, yb;
		float x0, y0, x1, y1;

		xb = xs + xd * i;
		yb = ys + yd * i;

		x0 = sweep_size * yd + xb;
		y0 = sweep_size * xd + yb;
		x1 = -sweep_size * yd + xb;
		y1 = -sweep_size * xd + yb;

		cb.reset();
		image.line_callback( x0, y0, x1, y1, cb );
		if ( inner )
		{
			printf("%g %g %g %g -> %d\n",
				x0, y0, x1, y1, cb.pixels_below_avg());
		}
		if ( !inner && cb.pixels_above_avg() > 25 )
		{
			return i;
		}
		if ( inner && cb.pixels_below_avg() > 25 )
		{
			return i;
		}
	}
}

main( int argc, char *argv[] )
{
	AIMAGE image;
	AIMAGE edge;
	APIXEL r( 1.0, 0.0, 0.0 );
	APIXEL b( 0.0, 0.0, 1.0 );

	AIMAGE_PPM_UTILS::load( image, "bigcol.ppm" );

	int width, height;
	image.get_dim( width, height );

	//edge.alloc_image( width, height );
	//edge.do_edge( image );

	//image.line( 10.2, 10.5, 700.5, 200.5, r );
	//image.line( 700.2, 10.5, 10.2, 200.5, r );

	float x;
	bool cal_done = false;
	int count = 0;
	float cal = 0.0f;
	bool firstline = false;
	bool secondline = false;

	float x0, y0, x1, y1;
	ACCUMCB cb_black;

	for ( x = 0.5; x < 16; ++x )
	{
		image.line_callback( x, 0.0f, x, height-1, cb_black );
	}
	cb_black.set_background();

	x0 = do_sweep( image, false,
		0.0, height/2, height/2-5, 1.0, 0.0, width, cb_black);
	x1 = ((float) width-1)-do_sweep( image, false,
		width-1, height/2, height/2-5, -1.0, 0.0, width, cb_black);
	y0 = do_sweep( image, false,
		width/2, 0.0, width/2-5, 0.0, 1.0, height, cb_black);
	y1 = ((float) height-1)-do_sweep( image, false,
		width/2, height-1, width/2-5, 0.0, -1.0, height, cb_black);

	float xw, yw;

	xw = x1 - x0;
	yw = y1 - y0;

	float xc, yc;

	xc = ( x0 + x1 ) * .5f;
	yc = ( y0 + y1 ) * .5f;

	printf("Width %g Height %g\n", xw, yw );

	image.line( xc - 10, yc, xc+10, yc, r );
	image.line( xc, yc-10, xc, yc+10, r );

	ACCUMCB cb_colored;

	float ix0, ix1, iy0, iy1;

	ix0 = xc - xw * .30;
	iy0 = yc - xw * .30;
	ix1 = xc + xw * .30;
	iy1 = yc + xw * .30;

	for ( x = 0.5; x < 5; ++x )
	{
		image.line_callback( x+ix0, iy0, x+ix0, iy1, cb_colored);
	}
	cb_colored.set_background();

	float iix0, iix1, iiy0, iiy1;

	iix0 = ix0 + do_sweep( image, true,
		ix0, yc, yw * 0.30, 1.0, 0.0, xw * 0.30, cb_colored);
	iix1 = ix1 - do_sweep( image, true,
		ix1, yc, yw * 0.30, -1.0, 0.0, xw * 0.30, cb_colored);
	iiy0 = iy0 + do_sweep( image, true,
		xc, iy0, xw * 0.30, 0.0, 1.0, yw * 0.30, cb_colored);
	iiy1 = iy1 - do_sweep( image, true,
		xc, iy1, xw * 0.30, 0.0, -1.0, yw * 0.30, cb_colored);

	image.line( x0, y0, x0, y1, r );
	image.line( x1, y0, x1, y1, r );
	image.line( x0, y0, x1, y0, r );
	image.line( x0, y1, x1, y1, r );

	image.line( iix0, iiy0, iix0, iiy1, b );
	image.line( iix1, iiy0, iix1, iiy1, b );
	image.line( iix0, iiy0, iix1, iiy0, b );
	image.line( iix0, iiy1, iix1, iiy1, b );

	image.line( ix0, iy0, ix0, iy1, r );
	image.line( ix1, iy0, ix1, iy1, r );
	image.line( ix0, iy0, ix1, iy0, r );
	image.line( ix0, iy1, ix1, iy1, r );

	float iixc = ( iix0 + iix1 ) * .5f;
	float iiyc = ( iiy0 + iiy1 ) * .5f;

	image.line( iixc - 10, iiyc, iixc+10, iiyc, b );
	image.line( iixc, iiyc-10, iixc, iiyc+10, b );
	
	image.view();
}

